YS電子工作ラボ

PWMによる
唱歌「ふるさと」

(→プロジェクトファイル(Harmony Ver.2.04版 ) ダウンロード


 PIC32MZのOCモジュールをPWMで動作させて、秋月電子通商の表面実装用スピーカー UM1515IAにより 唱歌「ふるさと」を演奏した
例を紹介します。

<仕様>
 ・ PIC32MZのOCモジュール(OC1)をPWMモードで使う。
 ・ Harmonyは OCモジュールはスタティクライブラリを使う。
 ・ スピーカは、秋月電子通商の表面実装用スピーカー UM1515IAとする。
    ・応答周波数: 850Hz~20KHz
    ・定格出力:0.5W
    ・最大出力:0.8W
    ・インピーダンス:8Ω
 ・ スピーカの音量調整がハードで行えるツマミを有する。
 ・演奏する 唱歌は「ふるさと」とし、下記楽譜の調(ヘ長調)、テンポ(80)、音符 及び休止符等に
  したがって スピーカの吹鳴周波数、吹鳴時間 及び休止時間等を定め演奏のこと。(参照→音楽の基礎知識



<回路図> (→ PDFファイル





<外観> PIC32MZ評価ボード(→購入方法)を使った実験品の外観です。

   



<動作結果> (→動画:1080pのHD動画を見ることができます。)

        唱歌「ふるさと」を 録音したMP3ファイルです。 PCで再生して聞いてください。。



<解説>  記載してある内容は要点だけです。 詳細はプロジェクトファイルを精読願います。
        (以下は、Harmony v2.04 をもとに作成しています。最新のバージョンとは異なる点があるかもしれませんので注意してください。)     


 ■ MHC設定
   Options

項目 ①Config設定 
Device & Project Configuration
  > PIC32MZ2048 Device Configuration
②OC設定
Harmony Framework Configuration > Drivers
 > OC 
③タイマ設定
Harmony Framework Configuration > Drivers
 > Timer 
MHC
備考 デフォルトからの変更要領:
 FPLLIDIV: DIV3
 FPLLICLK: PLL_POSC
 POSCMOD: EC

システムクロック周波数: 200MHz
外部OSC: 24MHz

#pragma config FNOSC = SPLL
#pragma config POSCMOD = EC
#pragma config FPLLIDIV = DIV_3
#pragma config FPLLICLK = PLL_POSC
#pragma config FPLLMULT = MUL_50
#pragma config FPLLODIV = DIV_2
デフォルトからの変更要領:
 □Use OC Driver? チェックを追加
 OC Module ID: OC_ID_1
 OC Modules:
      OC_COMPARE_PWM_EDGE_ALIGNED_MODE
デフォルトからの変更要領:
 Timer Module ID: TMR_ID_2
 Prescale: TMR_PRESCALE_VALUE_16

(注)□Use OC Driver? にチェックを追加すると
□Use Timer Driver?には MHCが自動的にチェックを追加してくれます。


   Pin Settings

項目 ④ポート設定
MHC
備考 デフォルトからの変更要領:
RD0/Functions: OC1


 ■ app.cに 青字部を追加します。 他のファイルへの追加は必要ありません。

  ① OC_ID_1がコンパイルできるようにperipheral/oc/plib_oc.hをインクルードします。
     四分音符の時間(長さ) T4 は、 60秒 ÷ テンポ(=80)なので、 T4 = 750 [msec] (=60 * 1000 / 80;
     #include "peripheral/oc/plib_oc.h" //これがないと OC_ID_1がコンパイルエラー
     int delay_Clock = 200000000; //200MHz
     int tempo_speed = 80; //テンポ=80
     int T4 = 750; //四分音符の時間(長さ) T4 = 750 [msec] //T4 = 60 * 1000 / 80;


  ② NOPを用いた 1μsec、1msecの遅延関数 delay_usec( )、delay_ms( )をつくります。
     void delay_us(volatile unsigned int usec) //1μsec遅延
     {
       volatile int count;
       count = (int)(delay_Clock/20000000)*usec;


  ③ 音階の違いは工学的には周波数の違いです。所要のPWM周波数に対応するタイマ2のPR2レジスタ値を
     設定します。また、OC1RSレジスタ値を設定してデューティの設定も行います。
     void BuzFreq(volatile int Freq, volatile float Duty) //PWM周波数(Freq) と デューティ(Duty)の設定関数
     {
       volatile int myPR; //PWM周期のレジスタ値( = PR2 at Timer2)
       volatile int myDuty; //PWM出力ON時間に相当するレジスタ値(= OC1RS at OC1)
       ……
       ……

  ④ 各音階に対するPWM周波数とデューティを設定します。
    下記は第四オクターブの ド です。 PWM周波数を261.63Hz、デューティを0.5に設定しています。
    人間の耳の感度に周波数特性、音量特性があるので必要に応じてデューティを変えます。
    void Do_C4(void) //第四オクターブ ド //C4
    {
      BuzFreq(261.63,0.5);//ド //261.63Hz
    }
    ……
    ……


  ⑤ APP_Initialize ( )のなかでOCをイネーブル(有効)にします。
    DRV_OC0_Enable(); //OC1 イネーブル


  ⑥ 繰り返しルーチンvoid APP_Tasks ( )のcase APP_STATE_SERVICE_TASKS:の中でメロディーに沿った
    音階をならべていきます。 delay_ms( )の遅延関数で音符長さを設定します。
    音階と次の音階の間に 若干無音の時間をいれた方が実際の音楽らしくなります。
    //第1行: うさぎ追いし かの山 -----------------------------------------------------------
    //-----第一小節

    Fa_F4(); //ファ
    delay_ms(T4); //四分音符長さ
    noSound();

    Fa_F4(); //ファ
    delay_ms(T4); //四分音符長さ
    noSound();

    ……
    ……



以下、app.c